<template>
    <d2-container class="crudNormal" type="full">
        <el-container>
            <el-aside width="200px" v-show="checkFun(funName.Tree)">
                <el-input placeholder="输入关键字进行过滤" v-model="filterText">
                </el-input>
                <el-tree class="filter-tree" :data="tree.data" :props="tree.defaultProps" default-expand-all :filter-node-method="filterNode" @node-click="nodeClick" ref="tree">
                </el-tree>
            </el-aside>
            <el-main>
                <query-form :fields="queryFormFields" ref="queryCard" v-show="queryFormFields.length>0"></query-form>
                <Search-Window :visible.sync="searchWindowVisible" :fields="advSearchFields" :modal="true" @click="onAdvSearchFilter" />
                <vxe-grid v-bind="gridOptions" ref="table" @checkbox-change="checkboxChangeEvent" @checkbox-all="checkboxChangeEvent" @toggle-row-expand="onRowExpand">
                    <template #expand>
                        <vxe-grid v-bind="expandOption" ref="expandTable">
                            <template #expand-toolbar ref="expand-toolbar">
                                <el-button-group class="d2-fr">
                                    <el-tooltip effect="dark" content="自定义打印" placement="bottom">
                                        <el-button type="primary" icon="el-icon-printer" plain circle @click="$refs.expandTable.openPrint()"></el-button>
                                    </el-tooltip>
                                    <el-tooltip effect="dark" content="导出数据到文件" placement="bottom">
                                        <el-button type="primary" icon="el-icon-download" plain circle @click="$refs.expandTable.openExport()"></el-button>
                                    </el-tooltip>
                                    <!-- <el-tooltip effect="dark" content="切换表格最大化" placement="bottom">
                                <el-button type="primary" icon="el-icon-full-screen" plain circle @click="$refs.expandTable.zoom()"></el-button>
                            </el-tooltip> -->
                                </el-button-group>
                            </template>
                            <template #expandBtn="{row}">
                                <el-dropdown @command="expandRowBtnClick">
                                    <span class="el-dropdown-link">
                                        功能<i class="el-icon-arrow-down el-icon--right"></i>
                                    </span>
                                    <el-dropdown-menu slot="dropdown">
                                        <el-dropdown-item v-for="(btn,idx) in config.expand.btns" :key="idx" :command="{cmd:btn.title,row:row,btn:btn}" v-show="btnCanShow(row,btn)">
                                            <i :class="btn.icon" v-show="btn.icon"></i> {{btn.title}}
                                        </el-dropdown-item>
                                    </el-dropdown-menu>
                                </el-dropdown>
                            </template>
                        </vxe-grid>
                    </template>
                    <template #toolbar_buttons ref="toolBar">
                        <el-button-group>
                            <el-button type="primary" @click="normalQuery" v-show="queryFormFields.length>0">
                                <d2-icon name="filter" plain></d2-icon> 查询
                            </el-button>
                            <el-button type="primary" @click="searchWindowVisible=true" v-show="advSearchFields.length>0">
                                <d2-icon name="magic" plain></d2-icon> 高级查询
                            </el-button>
                            <el-button type="primary" @click="addData" v-show="checkFun(funName.Add)">
                                <d2-icon name="plus" plain></d2-icon> 新增
                            </el-button>
                            <el-button type="primary" @click="batchAddData" v-show="checkFun(funName.BatchAdd)">
                                <d2-icon name="plus-square" plain></d2-icon> 批量新增
                            </el-button>
                            <el-button v-for="(btn,idx) in topBtn" :key="idx" :type="btn.type" @click="topBtnClick(btn)">
                                <i :class="btn.icon" plain v-show="btn.icon"></i> {{btn.title}}
                            </el-button>
                        </el-button-group>
                        <el-button-group class="d2-fr">
                            <el-tooltip effect="dark" content="加载数据" placement="bottom">
                                <el-button type="primary" icon="el-icon-refresh" plain circle @click="normalQuery"></el-button>
                            </el-tooltip>
                            <el-tooltip effect="dark" content="清除过滤条件" placement="bottom">
                                <el-button type="primary" icon="el-icon-refresh-right" plain circle @click="$refs.table.clearAll()"></el-button>
                            </el-tooltip>
                            <el-tooltip effect="dark" content="自定义打印" placement="bottom">
                                <el-button type="primary" icon="el-icon-printer" plain circle @click="$refs.table.openPrint()"></el-button>
                            </el-tooltip>
                            <el-tooltip effect="dark" content="导出数据到文件" placement="bottom">
                                <el-button type="primary" icon="el-icon-download" plain circle @click="$refs.table.openExport()"></el-button>
                            </el-tooltip>
                            <el-tooltip effect="dark" content="设置列显/隐" placement="bottom">
                                <el-button type="primary" icon="el-icon-s-grid" plain circle @click="$refs.table.$refs.xToolbar.showCustom()"></el-button>
                            </el-tooltip>
                            <el-tooltip effect="dark" content="恢复列显/隐" placement="bottom">
                                <el-button type="primary" icon="el-icon-refresh-left" plain circle @click="$refs.table.resetColumn({resizable:true})"></el-button>
                            </el-tooltip>
                            <el-tooltip effect="dark" content="切换表格最大化" placement="bottom">
                                <el-button type="primary" icon="el-icon-full-screen" plain circle @click="$refs.table.zoom()"></el-button>
                            </el-tooltip>
                        </el-button-group>
                    </template>
                    <template #operation="{row}">
                        <el-dropdown @command="rowBtnClick">
                            <span class="el-dropdown-link">
                                功能<i class="el-icon-arrow-down el-icon--right"></i>
                            </span>
                            <el-dropdown-menu slot="dropdown">
                                <el-dropdown-item :command="{cmd:'edit',row:row,btn:null}">
                                    <i class="fa fa-edit"></i> 修改
                                </el-dropdown-item>
                                <el-dropdown-item :command="{cmd:'del',row:row,btn:null}">
                                    <i class="fa fa-trash-o"></i> 删除
                                </el-dropdown-item>
                                <el-dropdown-item divided v-for="(btn,idx) in rowBtn" :key="idx" :command="{cmd:btn.title,row:row,btn:btn}" v-show="btnCanShow(row,btn)">
                                    <i :class="btn.icon" v-show="btn.icon"></i> {{btn.title}}
                                </el-dropdown-item>
                            </el-dropdown-menu>
                        </el-dropdown>
                    </template>
                    <template #pager>
                        <vxe-pager :layouts="['Sizes', 'PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'FullJump', 'Total']" border :current-page.sync="tablePage.currentPage" :page-size.sync="tablePage.pageSize" auto-hidden :page-sizes="[10,20,50,100,200,500,1000]" :total="tablePage.total" @page-change="handlePageChange">
                            <template #left v-show="footerBtn.length>0">
                                <span class="page-left">
                                    <vxe-checkbox v-model="checkConfig.isAllChecked" :indeterminate="checkConfig.isIndeterminate" @change="changeAllEvent"></vxe-checkbox>
                                    <span class="select-count">已选中 {{ checkConfig.selectRecords.length }} 条</span>

                                    <el-button-group>
                                        <el-button type="primary" @click="batchRemove">
                                            <i class="fa fa-trash-o"></i> 批量删除
                                        </el-button>

                                        <el-button v-for="(btn,idx) in footerBtn" :key="idx" :type="btn.type" @click="footBtnClick(btn)">
                                            <i :class="btn.icon" v-show="btn.icon"></i> {{btn.title}}
                                        </el-button>
                                    </el-button-group>
                                </span>
                            </template>
                        </vxe-pager>
                    </template>
                </vxe-grid>
            </el-main>
        </el-container>

    </d2-container>
</template>
<script>
import CRUDMixin from "./mixin";
import { filter, forEach, merge, keys } from "lodash";
import QueryForm from "./components/queryForm";
import SearchWindow from "@/components/adv-search/search-window";

export default {
    name: "NormalCRUDPage",
    mixins: [CRUDMixin],
    components: { QueryForm, SearchWindow },
    mounted() {
        this.$api.CRUD.QUERY_CONFIG_BYKEY(this.configKey).then(
            (res) => {
                this.config = res.config;
                this.initTableOption();
                this.normalQuery();
            },
            (err) => {
                this.$message.error({
                    message: `没有加载到configKey=${this.configKey}的配置项，请确认服务器内有无此配置`,
                    showClose: true,
                });
            }
        );
    },
    watch: {
        filterText(val) {
            this.$refs.tree.filter(val);
        },
    },
    data() {
        return {
            filterText: "",
            tree: {
                data: [],
                defaultProps: {
                    children: "children",
                    label: "label",
                },
            },
            advSearchParams: [], //最后一次高级查询时，配置的参数
            queryType: 1, //按普通查询出的数据为1   按高级查询出的数据为2   按左侧Tree查询出的数据=3
            //分页控件数据
            tablePage: {
                total: 85, //总行数
                currentPage: 1, //当前页
                pageSize: 10, //一页多少行
            },
            //表格参数
            gridOptions: {
                id: "normal-table-" + this.$route.meta.configKey,
                maxHeight: 800,
                exportConfig: {},
                printConfig: {},
                customConfig: { storage: true },
                toolbarConfig: {
                    custom: true,
                    slots: {
                        buttons: "toolbar_buttons",
                    },
                },
                columns: [],
                data: [],
            },
            //展开行时的表格配置参数
            expandOption: {
                id: "normal-child-table-" + this.$route.meta.configKey,
                maxHeight: 800,
                exportConfig: {},
                printConfig: {},
                size: "mini",
                toolbarConfig: {
                    slots: {
                        buttons: "expand-toolbar",
                    },
                },
                columns: [
                    { field: "f", title: "f" },
                    { field: "t", title: "t" },
                ],
                data: [
                    { f: 1, t: 1122 },
                    { f: 2, t: 10201 },
                ],
            },
            //后台加载的CRUD配置
            config: {
                key: "",
                fun: 0,
                btns: [],
                remark: {},
                fields: [],
            },
            //高级查询是否显示
            searchWindowVisible: false,
            //左下角选择按钮功能
            checkConfig: {
                isAllChecked: false,
                isIndeterminate: false,
                selectRecords: [],
            },
        };
    },
    computed: {
        //高级查询需显示的字段列表
        advSearchFields() {
            const typeRelation = {
                input: "string",
                inputnumber: "number",
                datepicker: "date",
                timepicker: "date",
                switch: "bool",
                select: "select",
            };
            const fields = filter(this.config.fields, (f) =>
                this.hasFlag(f.showFun, this.funName.AdvQuery)
            ).map((p) => {
                return {
                    field: p.field,
                    label: p.title,
                    value: p.value,
                    type: typeRelation[p.type.toLowerCase()],
                    config: {
                        type: p.props ? p.props.type : "",
                        options: p.options,
                        precision: p.props ? p.props.precision : 0,
                        max: p.props ? p.props.max : 9999999,
                        min: p.props ? p.props.min : 0,
                    },
                };
            });
            return fields;
        },
        //普通(本页面)查询需显示的字段列表
        queryFormFields() {
            const fields = filter(this.config.fields, (f) =>
                this.hasFlag(f.showFun, this.funName.Query)
            );
            return fields;
        },
        //行尾数据列
        showFootFields() {
            const fields = filter(this.config.fields, (f) =>
                this.hasFlag(f.showFun, this.funName.Footer)
            );
            return fields;
        },
        //显示在表格上面的按钮配置
        topBtn() {
            if (this.config.btns) {
                const fields = filter(
                    this.config.btns,
                    (f) => f.showType != undefined && f.showType == 1
                );
                return fields;
            } else {
                return [];
            }
        },
        //显示在表格每一行上的按钮配置
        rowBtn() {
            if (this.config.btns) {
                const fields = filter(
                    this.config.btns,
                    (f) => f.showType != undefined && f.showType == 2
                );
                return fields;
            } else {
                return [];
            }
        },
        //显示在表格每一行上的按钮配置
        footerBtn() {
            if (this.config.btns) {
                const fields = filter(
                    this.config.btns,
                    (f) => f.showType != undefined && f.showType == 3
                );
                return fields;
            } else {
                return [];
            }
        },
    },
    methods: {
        //判断fun内是否有值
        checkFun(funKey) {
            return this.hasFlag(this.config.fun, funKey);
        },
        //过滤tree
        filterNode(value, data) {
            if (!value) return true;
            return data.label.indexOf(value) !== -1;
        },
        //处理展开后的行的数据
        dealExpandQueryData(data) {
            this.expandOption.columns = [];
            this.expandOption.data = [];
            if (data.length > 0) {
                this.expandOption.columns.push({
                    title: "#",
                    type: "seq",
                    width: 36,
                    fixed: "left",
                });
                if (
                    this.config.expand &&
                    this.config.expand.btns &&
                    this.config.expand.btns.length > 0
                ) {
                    this.expandOption.columns.push({
                        title: "操作",
                        width: 70,
                        slots: { default: "expandBtn" },
                        fixed: "left",
                        resizable: false,
                    });
                }
                forEach(keys(data[0]), (c) => {
                    this.expandOption.columns.push({
                        title: c,
                        field: c,
                        sortable: true,
                    });
                });
                this.expandOption.data = data;
            }
        },
        //当行展开时发生
        onRowExpand({ expanded, row }) {
            if (expanded) {
                //展开时发生
                this.$api.CRUD.QUERY_EXPAND(this.configKey, row).then((res) => {
                    if (res.isOk) {
                        this.dealExpandQueryData(res.Result);
                    } else {
                        this.$message(res.errMsg);
                    }
                });
            }
        },
        nodeClick(data) {
            const id = data.id;
            const label = data.label;
            this.$refs.table.loadData([]);
            this.$api.CRUD.QUERY_BY_TREE(this.configKey, { id, label }).then(
                (data) => {
                    if (data.isOk) {
                        this.dealQueryData(data.Result);
                        this.initTableHeight();
                        this.queryType = 3;
                    } else {
                        this.$message(data.errMsg);
                    }
                }
            );
        },
        initTreeData() {
            if (this.checkFun(this.funName.Tree)) {
                var self = this;
                this.$api.CRUD.QUERY_TREE_DATA(this.configKey).then(
                    (res) => {
                        self.tree.data = res.Result;
                    },
                    (err) => {
                        self.$message.error({
                            message: `加载configKey=${self.configKey}的Tree配置项时发生异常，请确认服务器内有无此配置`,
                            showClose: true,
                        });
                    }
                );
            }
        },
        //初始化表格选项
        initTableOption() {
            this.gridOptions.rowId = this.config.key;
            this.initTableFootOption();
            this.initColumnOption();
            this.initTreeData();
        },
        //初始化表尾合计
        initTableFootOption() {
            const footFields = this.showFootFields;
            if (footFields.length > 0) {
                const needFootFieldNames = this.showFootFields.map(
                    (p) => p.field
                );
                this.gridOptions.showFooter = true;
                this.gridOptions.footerMethod = ({ columns, data }) => {
                    return [
                        columns.map((column, columnIndex) => {
                            if (columnIndex === 0) {
                                return "合计";
                            }
                            if (needFootFieldNames.includes(column.property)) {
                                let sum = 0;
                                data.forEach(
                                    (row) =>
                                        (sum += Number(row[column.property]))
                                );
                                return sum;
                            }
                            return null;
                        }),
                    ];
                };
            }
        },
        //列格式化
        colFormatter(field, { cellValue, row, column }) {
            switch (field.type.toLowerCase()) {
                case "select":
                    if (field.options) {
                        if (cellValue == undefined || cellValue == null)
                            return "";
                        var option = field.options.find(
                            (p) => p.value == cellValue
                        );
                        if (option != undefined) return option.label;
                    }
                case "datepicker":
                case "timepicker":
                    if (cellValue != undefined && cellValue != null) {
                        return cellValue.replace("T", " ");
                    }
                case "switch":
                    return cellValue
                        ? field.props.activeText
                        : field.props.inactiveText;
            }
            return cellValue;
        },
        //列筛选
        colFilter(field, col) {
            switch (field.type.toLowerCase()) {
                case "select":
                    col.filters = field.options;
                    col.filterMultiple = false;
                    col.filterMethod = (filterParams) => {
                        console.log(filterParams);
                        return (
                            filterParams.row[field.field] ==
                            filterParams.option.value
                        );
                    };
                    break;
                case "switch":
                    const option = [
                        { label: field.props.activeText, value: true },
                        { label: field.props.inactiveText, value: false },
                    ];
                    col.filters = option;
                    col.filterMultiple = false;
                    col.filterMethod = (filterParams) => {
                        console.log(filterParams);
                        return (
                            filterParams.row[field.field] ==
                            filterParams.option.value
                        );
                    };
                    breal;
            }
        },
        //初始化表格列选项
        initColumnOption() {
            //公用列
            if (this.checkFun(this.funName.Expand)) {
                this.gridOptions.columns.push({
                    title: "展开详情",
                    type: "expand",
                    width: 36,
                    resizable: false,
                    fixed: "left",
                    slots: { content: "expand" },
                });
            }
            this.gridOptions.columns.push({
                title: "#",
                type: "seq",
                width: 36,
                fixed: "left",
            });
            if (
                this.checkFun(this.funName.Edit) ||
                this.checkFun(this.funName.Del) ||
                this.rowBtn.length > 0
            ) {
                this.gridOptions.columns.push({
                    title: "操作",
                    width: 70,
                    slots: { default: "operation" },
                    fixed: "left",
                    resizable: false,
                });
            }
            if (this.footerBtn.length > 0) {
                this.gridOptions.columns.push({
                    title: "全选",
                    type: "checkbox",
                    width: 36,
                    resizable: false,
                    fixed: "left",
                });
            }
            //配置的个性化列
            forEach(this.config.fields, (f) => {
                if (
                    !this.config.remark ||
                    f.field != this.config.remark.remarkField
                ) {
                    if (this.hasFlag(f.showFun, this.funName.List)) {
                        let col = {
                            title: f.title,
                            field: f.field,
                            sortable: true,
                            formatter: ({ cellValue, row, column }) =>
                                this.colFormatter(f, {
                                    cellValue,
                                    row,
                                    column,
                                }),
                        };
                        this.colFilter(f, col);
                        this.gridOptions.columns.push(col);
                    }
                }
            });
            if (this.config.remark) {
                forEach(this.config.remark.fields, (f) => {
                    let col = {
                        title: f.title,
                        field: f.field,
                        sortable: true,
                        formatter: ({ cellValue, row, column }) =>
                            this.colFormatter(f, {
                                cellValue,
                                row,
                                column,
                            }),
                    };
                    this.colFilter(f, col);
                    this.gridOptions.columns.push(col);
                });
            }
        },
        //查询完毕后初始化表格高度
        initTableHeight() {
            const height = this.showFootFields.length > 0 ? 60 : 25;
            this.gridOptions.maxHeight =
                this.$el.clientHeight -
                this.$refs.queryCard.$el.clientHeight -
                height;
        },
        //分页按钮切换时
        handlePageChange(pageParams) {
            //{type: "current", pageSize: 10, currentPage: 5}
            if (this.queryType == 1) {
                this.normalQuery();
            } else if (this.queryType == 2) {
                this.onAdvSearchFilter();
            } else if (this.queryType == 3) {
                this.nodeClick(this.$refs.tree.getCurrentNode);
            }
        },
        //左下角选择框
        checkboxChangeEvent({ records }) {
            this.checkConfig.isAllChecked = this.$refs.table.isAllCheckboxChecked();
            this.checkConfig.isIndeterminate = this.$refs.table.isCheckboxIndeterminate();
            this.checkConfig.selectRecords = records;
        },
        //全选CheckBox
        changeAllEvent() {
            this.$refs.table.setAllCheckboxRow(this.checkConfig.isAllChecked);
            this.checkConfig.selectRecords = this.$refs.table.getCheckboxRecords();
        },
        //行内按钮 是否可用显示
        btnCanShow(row, btn) {
            if (btn.canShow != undefined && btn.canShow != null) {
                //btn.canShow 编写为一个lambda字符串，传入参数row，计算row内是否符合条件
                //把row转换成列表，调用filter方法，判断filter得到结果的数量是否为1，如果为1，则条件符合，则显示
                //由于后台配置为字符串，则把字符串转换成功可执行代码
                if (typeof btn.canShow == "string") {
                    return [row].filter(eval(btn.canShow)).length == 1;
                }
            }
            return true;
        },
        //处理获取到的后台数据，处理Remark后赋值给this.tableData
        dealQueryData(data) {
            let ret = data.data;
            if (this.config.remark) {
                forEach(ret, (p) => {
                    const remarkVal = p[this.config.remark.remarkField];
                    if (remarkVal) {
                        const remarkObj = JSON.parse(remarkVal);
                        merge(p, remarkObj);
                    }
                });
            }
            // this.gridOptions.Data = ret;
            this.$refs.table.loadData(ret);
            this.tablePage.total = data.total;
        },
        //普通查询
        normalQuery() {
            const queryData = this.$refs.queryCard.getData();
            this.$refs.table.loadData([]);
            this.$api.CRUD.NORMAL_QUERY(
                this.configKey,
                queryData,
                this.tablePage
            ).then((data) => {
                if (data.isOk) {
                    this.dealQueryData(data.Result);
                    this.initTableHeight();
                    this.queryType = 1;
                } else {
                    this.$message(data.errMsg);
                }
            });
        },
        //高级查询过滤方法
        onAdvSearchFilter(params) {
            console.log("params", params);
            if (params == undefined) {
                params = this.advSearchParams;
            }
            this.advSearchParams = params;
            this.$refs.table.loadData([]);
            this.$api.CRUD.ADV_QUERY(
                this.configKey,
                params,
                this.tablePage
            ).then((data) => {
                if (data.isOk) {
                    this.dealQueryData(data.Result);
                    this.initTableHeight();
                    this.queryType = 2;
                } else {
                    this.$message(data.errMsg);
                }
            });
            this.searchWindowVisible = false;
        },
        //新增按钮
        addData() {
            console.log("toolBar", this.$refs);
        },
        //批量新增按钮
        batchAddData() {},
        //批量删除按钮点击时
        batchRemove() {},
        //自定义表头按钮点击事件
        topBtnClick(btn) {},
        //行按钮点击时触发
        rowBtnClick({ cmd, row, btn }) {
            console.log("cmd", cmd);
            console.log("row", row);
            console.log("btn", btn);
        },
        //表尾按钮点击时触发
        footBtnClick(btn) {},

        //子表内的按钮
        expandRowBtnClick({ cmd, row, btn }) {},
    },
};
</script>
<style>
.el-main,
.vxe-body--expanded-cell {
    padding: 0px;
}
.vxe-custom--wrapper button {
    display: none;
}
.page-left {
    position: absolute;
    left: 10px;
    top: 50%;
    transform: translateY(-50%);
    z-index: 10;
}
</style>